package br.com.cpqd.ssar.utilitarias;

import java.util.LinkedList;

public class Esfera extends AtributosGeometria {

    private float radius;
    private double Pi = 3.1415926535898;
    private LinkedList listVertexLong = new LinkedList();
    private LinkedList listFacesTriangulares = new LinkedList();
    private Triangulo[] listaTriangulos = null;

    /**
     * 
     * @param radius
     * @param reference
     * @param id
     */
    public Esfera(float radius, float[] reference, int id) {
        super(reference, id);
        this.radius = radius;

    }   

    public float getRaio() {
        return radius;
    }

    public void setRaio(float radius) {
        this.radius = radius;
    }

    @Override
    public float getAltura() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setAltura(float height) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 
     * @return
     */
    @Override
    public float[] getFirsPoint() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 
     * @return
     */
    @Override
    public float[] getSecondPoint() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 
     * @param secondPoint
     */
    @Override
    public void setSecondPoint(float[] secondPoint) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 
     * @param firstPoint
     */
    @Override
    public void setFirsPoint(float[] firstPoint) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 
     * @return
     */
    public Triangulo[] triangularizarGeometria() {

        listFacesTriangulares.clear();
        listVertexLong.clear();
        double theta, fi;                      /* angulos de parametrizacao da esfera */
        float definicao = 0.5f;               /* definicao da malha poligonal */

        /* desenha as fatias longitudinais 
         * triangularizacao de acordo com as fatias longitudinais
         */

        for (fi = 0; fi <= (Pi); fi += Pi / 15) {  //15 = SLICES

            for (theta = 0; theta <= 2 * Pi; theta += definicao) {

                float[] coordenada = new float[3];
                float x = (float) (radius * Math.cos(theta) * Math.sin(fi));
                float y = (float) (radius * Math.sin(theta) * Math.sin(fi));
                float z = (float) (radius * Math.cos(fi));
                coordenada[0] = referencial[0] + x;
                coordenada[1] = referencial[1] + y;
                coordenada[2] = referencial[2] + z;
                Vertice vertex = new Vertice(coordenada);
                listVertexLong.add(vertex);

            }

        }
        /* triangularizando
         * 1 parte da esfera, 12 iteracoes para a tampa
         * vertices 0 (centro) ao 13
         */
        Vertice vertexCentro = (Vertice) listVertexLong.get(0); //recebe o vertice 0 (centro)

        for (int i = 1; i < 25; i++) {

            Vertice[] vectorV = new Vertice[3];
            Vertice vertexAux = (Vertice) listVertexLong.get(i);
            Vertice vertexAux2 = (Vertice) listVertexLong.get(i + 1);
            //calculando a normal dos 3 vertices
            float[] vectorNormal = super.calcVetorNormal(vertexCentro, vertexAux, vertexAux2);
            vectorV[0] = vertexCentro;
            vectorV[1] = vertexAux;
            vectorV[2] = vertexAux2;
            Triangulo faceTriangular = new Triangulo(vectorV, vectorNormal);

            if ((faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(1).getCoordenada(0)) && (faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(2).getCoordenada(0))) {

                if ((faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(1).getCoordenada(1)) && (faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(2).getCoordenada(1))) {

                    if ((faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(1).getCoordenada(2)) && (faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(2).getCoordenada(2))) {
                    }
                }
            } else {
                listFacesTriangulares.add(faceTriangular);
            }

        }//fim for

        /* calcula as faces entre as 'duas tampas' da esfera
         * a cada iteracao, sao armazenadas 2 faces e a cada
         * 12 iteracoes uma 'camada' da esfera Ã© triangularizada
         * */
        int v = 1; //representa o comeco da segunda camada a ser triangularizada
        // logo apos a 'tampa' ser triangularizada

        for (int j = 13; j < listVertexLong.size() - 2; j++) {

            Vertice[] vectorV = new Vertice[3];
            Vertice vertex = (Vertice) listVertexLong.get(v);
            Vertice vertexAux = (Vertice) listVertexLong.get(j + 1);
            Vertice vertexAux2 = (Vertice) listVertexLong.get(v + 1);
            float[] vectorNormal = super.calcVetorNormal(vertex, vertexAux, vertexAux2);
            vectorV[0] = vertex;
            vectorV[1] = vertexAux;
            vectorV[2] = vertexAux2;
            Triangulo faceTriangular = new Triangulo(vectorV, vectorNormal);
            if ((faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(1).getCoordenada(0)) && (faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(2).getCoordenada(0))) {

                if ((faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(1).getCoordenada(1)) && (faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(2).getCoordenada(1))) {

                    if ((faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(1).getCoordenada(2)) && (faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(2).getCoordenada(2))) {
                    }
                }
            } else {
                listFacesTriangulares.add(faceTriangular);
            }

            Vertice[] vectorVLong = new Vertice[3];
            Vertice vertexLong = (Vertice) listVertexLong.get(v + 1);
            Vertice vertexAuxLong = (Vertice) listVertexLong.get(j + 1);
            Vertice vertexAux2Long = (Vertice) listVertexLong.get(j + 2);
            float[] vectorNormalLong = super.calcVetorNormal(vertexLong, vertexAuxLong, vertexAux2Long);
            vectorVLong[0] = vertexLong;
            vectorVLong[1] = vertexAuxLong;
            vectorVLong[2] = vertexAux2Long;
            Triangulo faceTriangularLong = new Triangulo(vectorVLong, vectorNormalLong);

            if ((faceTriangularLong.getVertice(0).getCoordenada(0) == faceTriangularLong.getVertice(1).getCoordenada(0)) && (faceTriangularLong.getVertice(0).getCoordenada(0) == faceTriangularLong.getVertice(2).getCoordenada(0))) {

                if ((faceTriangularLong.getVertice(0).getCoordenada(1) == faceTriangularLong.getVertice(1).getCoordenada(1)) && (faceTriangularLong.getVertice(0).getCoordenada(1) == faceTriangularLong.getVertice(2).getCoordenada(1))) {

                    if ((faceTriangularLong.getVertice(0).getCoordenada(2) == faceTriangularLong.getVertice(1).getCoordenada(2)) && (faceTriangularLong.getVertice(0).getCoordenada(2) == faceTriangularLong.getVertice(2).getCoordenada(2))) {
                    }
                }
            } else {
                listFacesTriangulares.add(faceTriangularLong);
                v++;
            }
        // v++;
        }

        /* Recebe o ultimo vertice(centro) de baixo da esfera para triangularizar */
        Vertice vertexCentroBase = (Vertice) listVertexLong.getLast();
        for (int b = listVertexLong.size(); b < listVertexLong.size() - 13; b--) {

            Vertice[] vectorV = new Vertice[3];
            Vertice vertexAux = (Vertice) listVertexLong.get(b);
            Vertice vertexAux2 = (Vertice) listVertexLong.get(b - 1);
            //calculando a normal dos 3 vertices
            float[] vectorNormal = super.calcVetorNormal(vertexCentroBase, vertexAux, vertexAux2);
            vectorV[0] = vertexCentroBase;
            vectorV[1] = vertexAux;
            vectorV[2] = vertexAux2;
            Triangulo faceTriangular = new Triangulo(vectorV, vectorNormal);

            if ((faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(1).getCoordenada(0)) && (faceTriangular.getVertice(0).getCoordenada(0) == faceTriangular.getVertice(2).getCoordenada(0))) {

                if ((faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(1).getCoordenada(1)) && (faceTriangular.getVertice(0).getCoordenada(1) == faceTriangular.getVertice(2).getCoordenada(1))) {

                    if ((faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(1).getCoordenada(2)) && (faceTriangular.getVertice(0).getCoordenada(2) == faceTriangular.getVertice(2).getCoordenada(2))) {
                    }
                }
            } else {
                listFacesTriangulares.add(faceTriangular);
            }

        }

        listaTriangulos = new Triangulo[listFacesTriangulares.size()];
        for (int i = 0; i < listFacesTriangulares.size(); i++) {
            listaTriangulos[i] = (Triangulo) listFacesTriangulares.get(i);

        }

        return listaTriangulos;

    }

    @Override
    public int getDiscretizacaoX() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoX(int discretizacaoX) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getDiscretizacaoY() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoY(int discretizacaoY) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getDiscretizacaoZ() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoZ(int discretizacaoZ) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDx() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDy() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDz() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlXi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlXi(int pmlXi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlXf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlXf(int pmlXf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlYi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlYi(int pmlYi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlYf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlYf(int pmlYf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlZi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlZi(int pmlZi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlZf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlZf(int pmlZf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getEscala() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEscala(double escala) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEscala(String tipo) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void addX() {
        this.referencial[0] += 1;
    }

    @Override
    public void addY() {
        referencial[1] += 1;
    }

    @Override
    public void addZ() {
        referencial[2] += 1;
    }

    @Override
    public void subX() {
        referencial[0] -= 1;
    }

    @Override
    public void subY() {
        referencial[1] -= 1;
    }

    @Override
    public void subZ() {
        referencial[2] -= 1;
    }

    @Override
    public void redimensionar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    
    @Override
    public String getCaminhoArquivo() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setCaminhoArquivo(String caminhoArquivo) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getNSteps() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void addX(float valor) {
          this.referencial[0] += valor;
    }

    @Override
    public void addY(float valor) {
         this.referencial[1] += valor;
    }

    @Override
    public void addZ(float valor) {
        this.referencial[2] += valor;
    }

    @Override
    public void setNElements(int n){
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Triangulo[] getListaTriangulosSTL(){
        throw new UnsupportedOperationException("Not supported yet.");
    }

   @Override
    public int getNElements(){
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void redimensionarSTL(float[] min, float[] max){
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
     @Override
    public void subX(float valor) {
       referencial[0] -= valor;
    }

    @Override
    public void subY(float valor) {
       referencial[1] -= valor;
    }

    @Override
    public void subZ(float valor) {
        referencial[2] -= valor;
    }
}